package org.languageguide.user;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.languageguide.storage.DBConnector;

public class UserManager {	

	public static final int SECONDS_PER_YEAR = 60*60*24*365;
	
	public static User getUser(HttpSession session){
		Object obj = session.getAttribute(User.sessionId);
		if (obj != null)
			return (User)obj;
		else return null;
	}

	public void removeUser(HttpSession session){
		session.removeAttribute(User.sessionId);
	}
	
	public void forgetUser(HttpServletRequest request, HttpServletResponse response){
		Cookie[] cookies = request.getCookies();
        if(cookies == null || cookies.length < 1) {
        	return;
        }
        
        for (Cookie cookie : cookies) {
        	System.out.println("name = " + cookie.getName());
            if ("user".equalsIgnoreCase(cookie.getName())) {
            	System.out.println("cookie to delete found");
            	Cookie delcookie = new Cookie("user", cookie.getValue());
            	delcookie.setMaxAge(0); // delete cookie
            	delcookie.setPath(cookie.getPath()); // cookie won't delete in mozilla browsers unless set
            	delcookie.setDomain(cookie.getDomain());
            	response.addCookie(delcookie);
        		
        		System.out.println("cookie added to response");
        		return;
            }
        }
	}
	
	public void rememberUser(HttpSession session, HttpServletResponse response){
		User user = (User) session.getAttribute(User.sessionId);
		Cookie cookie = new Cookie("user", user.getEmail() + "&" + user.getHashedPw());
		cookie.setMaxAge(SECONDS_PER_YEAR);
		response.addCookie(cookie);
	}

	public static User loginFromCookie(HttpServletRequest request){
		String value = getUserCookieValue(request);
		System.out.println("value:" + value);
		if (value != null){
			int loc = value.indexOf("&");
			String[] rslts = loc != -1 ? value.split("&") : null;
			System.out.println("rslts[0]:" +rslts[0]);
			User user = getUser(rslts[0]);
			if (user != null){
				System.out.println("user not null" + user.getHashedPw());
				System.out.println("user not null" + rslts[1]);
				if (user.getHashedPw().equals(rslts[1])){
					System.out.println("we got a user");
					request.getSession().setAttribute(User.sessionId, user);
					return user;
				}
				//delete invalid cookie; 
			}			
		}
		return null;
		//Cookie tokenCookie = createTokenCookie(user);
		//log.debug("Created token cookie : " + tokenCookie);
	}	
	
	public static User getUser(String email){
		String hsUserSql = "SELECT * FROM Users2 WHERE Users2.email = ?";
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			PreparedStatement queryUser = connection.prepareStatement(hsUserSql);
			queryUser.setString(1, email);
			ResultSet rs = queryUser.executeQuery();
			while (rs.next()){
				User user = new User(rs);
				return user;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			connector.close(connection);
		}
		System.out.println("coun't find user");
		return null;
	}
	
	public void saveWord(String id, String language, String target, User user){
		//String sql = "INSERT INTO SavedWords (Id, Language, TargetLanguage, UserId) VALUES (?, ?, ?, ?);";
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			PreparedStatement saveWords = connection.prepareStatement(hsUserSql);
			saveWords.setString(1, id);
			saveWords.setString(2, language);
			saveWords.setString(3, target);
			saveWords.setInt(4, user.getIdInteger());
			saveWords.execute();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			connector.close(connection);
		}
	}
	
	
	public User getUser(String email, String pw){
		String hsUserSql = "SELECT * FROM Users2 WHERE Users2.email = ? AND HashPassword = ?"; // OR Password = ?
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		String hashed = PasswordUtility.getHash(pw);
		try {
			PreparedStatement queryUser = connection.prepareStatement(hsUserSql);
			queryUser.setString(1, email);
			queryUser.setString(2, hashed);
			//queryUser.setString(3, pw);
			ResultSet rs = queryUser.executeQuery();
			while (rs.next()){
				User user = new User(rs);
				return user;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			connector.close(connection);
		}
		System.out.println("coun't find user");
		return null;
	}

	public static String getUserCookieValue(HttpServletRequest request){
		Cookie[] cookies = request.getCookies();
		if(cookies == null || cookies.length < 1) {
			return null;
		}

		for (javax.servlet.http.Cookie cookie : cookies) {
			//System.out.println("name:" + cookie.getName() + ":");
			if (cookie.getName().equals("user")) {
				return cookie.getValue();
			}
		}
		return null;
	}


	public User registerUser(String name, String username, String email, String password, String lang){
		User user = new User(name, username, email, password, lang);
		user.store();
		return user;
	}

	
	
	String hsUserNameSql = "SELECT * FROM Users2 WHERE Users2.username = ?";
	public boolean hasUserName(String userName){
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			PreparedStatement queryUser = connection.prepareStatement(hsUserNameSql);
			queryUser.setString(1, userName); 
			ResultSet rs = queryUser.executeQuery();
			while (rs.next()){
				return true;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			connector.close(connection);
		}
		System.out.println("coun't find user");
		return false;
	}
	
	

	String hsUserSql = "SELECT * FROM Users2 WHERE Users2.email = ?";
	public boolean hasUser(String email){
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			PreparedStatement queryUser = connection.prepareStatement(hsUserSql);
			queryUser.setString(1, email); 
			ResultSet rs = queryUser.executeQuery();
			while (rs.next()){
				return true;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			connector.close(connection);
		}
		System.out.println("coun't find user");
		return false;
	}
	
	
	public boolean confirmEmail(String code){
		String verifyUserSql = "Update Users2 SET Confirmed = 1 WHERE Code = ?";
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			PreparedStatement confirmUserEmail = connection.prepareStatement(verifyUserSql);
			confirmUserEmail.setString(1, code); 
			confirmUserEmail.execute();
			int count = confirmUserEmail.getUpdateCount();
			if (count > 0){
				return true;
			}
			else{
				return false;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{
			connector.close(connection);
		}
		System.out.println("coun't find user");
		return false;
	}
		
	public boolean loadUser(HttpSession session, String email, String password){
		String sql = "SELECT * FROM Users2 LEFT JOIN Language ON Users2.editing_language = Language.code WHERE Users2.hashed_password = ? AND (Users2.email = ? OR Users2.username = ?)";
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		String hashed = PasswordUtility.getHash(password);
		
		
		try {
			PreparedStatement queryUser = connection.prepareStatement(sql);
			System.out.println(sql);
			queryUser.setString(1, hashed);
			queryUser.setString(2, email); 
			queryUser.setString(3, email);
			ResultSet rs = queryUser.executeQuery();
			while (rs.next()){
				System.out.println("found user");				
				User bean = new User(rs);
				
				session.setAttribute(User.sessionId, bean);
				return true;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{	
			connector.close(connection);
		}
		return false;
	}
	
	/*public boolean checkforPWErrors(){
		System.out.println("searchesching miss mat");
		String sql = "SELECT * FROM Users2";
		String sqlUpdateSql = "Update Users2 SET hashed_password = ? WHERE userid = ?";
		DBConnector connector = DBConnector.getInstance();
		Connection connection = connector.getConnection();
		try {
			PreparedStatement queryUser = connection.prepareStatement(sql);
			//PreparedStatement sqlUpdate = connection.prepareStatement(sqlUpdateSql);
			ResultSet rs = queryUser.executeQuery();
			while (rs.next()){
				
				String hashedPassword = rs.getString("hashed_password");
				//String password = rs.getString("password");
				String hashed = PasswordUtility.getHash(password);
				if (!hashed.equals(hashedPassword)){
					Integer id = rs.getInt("userid");
					System.out.println(id);
					System.out.println(password);
					//sqlUpdate.setString(1, hashed);
					//sqlUpdate.setInt(2, id);
					//sqlUpdate.addBatch();
				}
			}		
			//sqlUpdate.executeBatch();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		finally{	
			connector.close(connection);
		}
		return false;
	}*/
	
	
	public static void main(String[] args) {
		User user = UserManager.getUser("tom@languageguide.org");
		System.out.println("" + user);
	}
	
}
